home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The X-Philes (2nd Revision)
/
The X-Philes Number 1 (1995).iso
/
xphiles
/
hp48_2
/
h_piper_.src
< prev
next >
Wrap
Internet Message Format
|
1995-03-31
|
38KB
Path: ecsgate!mcnc!gatech!prism!vapsppr
From: vapsppr@prism.gatech.EDU (Paul Raines)
Newsgroups: comp.sys.handhelds
Subject: H. Piper! ver 2.0 (SOURCE CODE)
Message-ID: <29881@hydra.gatech.EDU>
Date: 26 May 91 16:23:39 GMT
Organization: Georgia Institute of Technology
Lines: 1042
The source code in Chipper for ver 2.0 of H. Piper! follows
below. There are some significant changes in some of the
logic. For people having problems with getting the ASC
version to run, try compiling this program and using its
output.
; H. Piper Game for the HP48SX
; (c) Paul Raines
; Register usage:
; V0: Temporary data, may change during any call
; V1: Temporary data, may change during any call
; V2: Temporary data, may change during any call
; V3: Temporary data, may change during any call
; V4: Temporary data, may change during any call
; V5: Temporary data, may change during any call
; V6: Temporary data, may change during any call
; V7: Current Job Score (ones & tens)
; V8: Current Job Score (hundreds & up)
; V9: Current Box type
; VA: Box progression
; VB: Flow direction
; VC: Current Box pos
; VD: Paddle position
; VE: Speed Level
; VF: Flag register
; NOTE: Box position is stored in one register such that
; #34h
; y pos --^^--- x pos on grid
;
; Two registers are used for the score in order to
; have a decimal number greater than 255.
; *************************
; START OF DEFINITIONS AREA
; *************************
F_UP = #00 ; direction definitions
F_DOWN = #03
F_RIGHT = #06
F_LEFT = #05
B_NE = #1D ; pipe definitions
B_SW = #15
B_NW = #1E ; NOTE THAT
B_SE = #16 ;
B_VERT = #01 ; B_SE xor F_UP and #07 = F_RIGHT
B_HORZ = #02 ; B_SW xor F_UP and #07 = F_LEFT
B_CROS = #03 ; B_NE xor F_LEFT and #07 = F_UP
B_ESTR = #07 ; ...
B_WSTR = #08 ; ...
B_NSTR = #09
B_SSTR = #0A
; Key definitions
; ( 7 ) -> #1 ( 8 ) -> #2 ( 9 ) -> #3 ( / ) -> #C
; ( 4 ) -> #4 ( 5 ) -> #5 ( 6 ) -> #6 ( * ) -> #D
; ( 1 ) -> #7 ( 2 ) -> #8 ( 3 ) -> #9 ( - ) -> #E
; ( 0 ) -> #A ( . ) -> #0 ( _ ) -> #B ( + ) -> #F
K_LEFT = #07
K_RIGHT = #08
K_UP = #03
K_DOWN = #06
K_FAST = #0F
K_PLACE = #01
K_UPLACE = #04
TYPERATE = #90 ; repeat rate for holding down key
; ******************
; START OF CODE AREA
; ******************
JP FIRST
COPYRIGHT: DA 'v2.0 Raines (c) 1991'
FIRST: DB #00, #FF ; turnon extend mode
DB #F3, #85 ; read incoming paused score and level
LD VE, V2 ; starting level
SNE V3, #1 ; if resuming paused game
JP RESUME
LD VE, #4E ; starting level
LD V0, 0 ; Zero out total score
LD V1, 0 ; " "
RESUME: LD I, TSCORE ; Set total score from flags
LD [I], V1 ; " "
LD VC, #FF ; signal for random starting placement
LD V0, 0
LD V1, 0
LD V2, 0
DB #F2, #75 ; clear user flags
; *** SETUP SCREEN, DATA AREA, AND REGISTERS FOR GAME PLAY ***
START: CLS
LD V0, #0B ; Fill grid array data
LD V1, #00 ; area with unfilled
LD V2, 0 ; unused grid sites
CLEARGRID: LD I, BOXINFO ; " "
ADD I, V2 ; " "
LD [I], V1 ; " "
ADD V2, 2 ; " "
SE V2, 120 ; " "
JP CLEARGRID ; " "
LD V0, #00 ; Fill preview array data
LD V2, 0 ; area with blank blocks
CLEARPREV: LD I, PBOXINFO ; " "
ADD I, V2 ; " "
LD [I], V1 ; " "
ADD V2, 2 ; " "
SE V2, 6 ; " "
JP CLEARPREV ; " "
LD I, TITLE ; Draw title "H. Piper!"
LD V0, 38
LD V1, 57
LD V3, 0
DRAWTITLE: ADD I, V3
DRW V0, V1, 5
LD V3, 5
ADD V0, 8
SE V0, 70
JP DRAWTITLE
LD I, HDSCORE ; Draw score and level heading
LD V0, 104
LD V1, 2
DRW V0, V1, 5
ADD V0, 8
LD V2, 5
ADD I, V2
DRW V0, V1, 5
LD I, HDLEVEL
LD V0, 104
LD V1, 42
DRW V0, V1, 5
ADD V0, 8
LD V2, 5
ADD I, V2
DRW V0, V1, 5
LD V1, VE ; draw needed score
SHR V1
LD V0, 100
SUB V0, V1 ; determine needed score
LD I, TEMP
LD B, V0 ; write BCD of needed score
LD V2, [I] ; read BCD in three parts
LD V3, 90
LD V4, 57
LD F, V1 ; point to sprite of tens digit
DRW V3, V4, 5 ; draw it
ADD V3, 5
LD F, V2 ; point to sprite of ones digit
DRW V3, V4, 5 ; draw it
LD V0, VE ; store the current level in memory
LD I, LEVEL ; in case some uses FAST key
LD [I], V0
LD I, HORZBOX ; draw top border
LD V0, 0
LD V1, 0
RDTOP: DRW V0, V1, 2
ADD V0, 8
SE V0, 96
JP RDTOP
LD V4, 2
RDPRV: LD I, PRV1BOX ; Draw preview boxes grids
LD V0, 0
DRW V0, V4, 12
LD I, PRV2BOX
LD V0, 8
DRW V0, V4, 12
ADD V4, 12
SE V4, 62
JP RDPRV
LD V7, 0
PREVAGAIN: LD V0, V7 ; favor corners for first 4 preview boxes
CALL GETRANDBLK ; randomly get five new
ADD V7, 1 ; preview boxes
SE V7, 5
JP PREVAGAIN
LD V1, 50 ; draw bottom border
LD V0, 16
LD I, FULLBOX
RDBBDR: DRW V0, V1, 6
ADD V0, 8
SE V0, 96
JP RDBBDR
LD V1, 0 ; Draw right border
LD V0, 96
LD I, RBORDER
RDRBDR: DRW V0, V1, 2
ADD V1, 2
SE V1, 56
JP RDRBDR
LD VD, #34 ; Draw initial paddles
CALL DRAWBPADL
CALL DRAWSPADL
CALL DRAWCRSHR
LD V1, 2 ; Draw grid boxes
LD I, GRID
RDGRID1: LD V0, 16
RDGRID2: DRW V0, V1, 8
ADD V0, 8
SE V0, 96
JP RDGRID2
ADD V1, 8
SE V1, 50
JP RDGRID1
SNE VC, #FF ; get starting direction and box
JP RANDSTART ; if not first job, use last box
NOTCORNER: SNE VB, #00 ;if last direction was down
LD V3, #6 ; make start direction up
SNE VB, #03 ;if last direction was up
LD V3, #4 ; make start direction down
SNE VB, #06 ;if last direction was right
LD V3, #2 ; make start direction left
SNE VB, #05 ;if last direction was left
LD V3, #0 ; make start direction right
JP SETUP
RANDSTART: RND V3, 7 ; Draw random starting box
ADD V3, 1
RND VC, #30
ADD VC, #10
ADD VC, V3 ; get random placement
RND V3, 3
SHL V3
SETUP: LD I, RANDDIR
ADD I, V3 ; get random direction of opening
LD V1, [I]
LD VB, V0 ; starting flow direction
LD V2, V1
LD V9, V2 ; starting box type
LD V0, VC
CALL DRAWBOX
CALL GETBOXTYPE ; prevent change of starting box
LD VA, 2 ; set starting progression
CALL DRAWRANDB
LD V7, 0 ; zero current job score
LD V8, 0
CALL WRITESCORE
CALL WRITELEVEL
LD V0, #FF ; maximum delay of progression
LD DT, V0 ; for beginning of game
; *** MAIN PROCEDURE FOR PLAYING GAME ***
GAMELOOP:
LD V0, K_LEFT
SKNP V0
CALL MOVELEFT ; move left if K_LEFT key pressed
LD V0, K_RIGHT
SKNP V0
CALL MOVERIGHT ; move right
LD V0, K_UP
SKNP V0
CALL MOVEUP ; move up
LD V0, K_DOWN
SKNP V0
CALL MOVEDOWN ; move down
LD V0, K_PLACE
SKNP V0
CALL PLACEBOX ; place box
LD V0, K_UPLACE
SKNP V0
CALL UPLACEBOX ; place box and use block shown for new
LD V0, K_FAST
SKNP V0
LD VE, #02 ; go fast
LD V0, DT
SNE V0, 0
CALL PROGRESS
JP GAMELOOP
; *****************************
; START OF SUBROUTINE CODE AREA
; *****************************
; Places next box on a grid site if allowed and updates preview boxes
; V1 - V5 modified
PLACEBOX: LD V0, #F ; don't favor corners
CALL GETRANDBLK ; get next box type (V2) and update preview
LD V0, VD ; get pos to draw box
CALL DRAWBOX ; draw box (V2) at desired box coord
RET
; Places next box on a grid site if allowed and updates preview boxes
; V1 - V5 modified
UPLACEBOX: CALL NEWPREV ; get next box type (V2) and update preview
LD V0, VD ; get pos to draw box
CALL DRAWBOX ; draw box (V2) at desired box coord
RET
; Takes paddle coord in VD and put x coord in V0, y coord in V1
; V0 := (out) paddle x coord
; V1 := (out) paddle y coord
; VD := bott coord
SPLITPOS: LD V0, VD
LD V1, #0F
AND V0, V1 ; store x part in V0
LD V1, VD
SUB V1, V0 ; store y part in V1
RET
; The following 4 subroutines move the crosshair in the desired direction
; V0 := --- (m)
; V1 := --- (m)
; VD := paddle coord
MOVELEFT: CALL DRAWBPADL ;erase old paddle
CALL DRAWCRSHR
CALL SPLITPOS ; calculate new pos
ADD V0, #FF ; "
SNE V0, #FF ; "
LD V0, 0 ; "
LD VD, V1 ; save new pos
ADD VD, V0
CALL DRAWBPADL ; draw new position
CALL DRAWCRSHR
LD V0, TYPERATE
CALL PAUSE
RET
MOVERIGHT: CALL DRAWBPADL ;erase old paddle
CALL DRAWCRSHR
CALL SPLITPOS ; calculate new pos
ADD V0, #01 ; "
SNE V0, #0A ; "
LD V0, 9 ; "
LD VD, V1 ; save new pos
ADD VD, V0
CALL DRAWBPADL ; draw new position
CALL DRAWCRSHR
LD V0, TYPERATE
CALL PAUSE
;NORIGHT: LD V0, K_RIGHT ; wait till key released
; SKNP V0
; JP NORIGHT
RET
MOVEUP: CALL DRAWSPADL ;erase old paddle
CALL DRAWCRSHR
CALL SPLITPOS ; calculate new pos
ADD V1, #F0 ; "
SNE V1, #F0 ; "
LD V1, 0 ; "
LD VD, V1 ; save new pos
ADD VD, V0
CALL DRAWSPADL ; draw new position
CALL DRAWCRSHR
LD V0, TYPERATE
CALL PAUSE
RET
MOVEDOWN: CALL DRAWSPADL ;erase old paddle
CALL DRAWCRSHR
CALL SPLITPOS ; calculate new pos
ADD V1, #10 ; "
SNE V1, #60 ; "
LD V1, #50 ; "
LD VD, V1 ; save new pos
ADD VD, V0
CALL DRAWSPADL ; draw new position
CALL DRAWCRSHR
LD V0, TYPERATE
CALL PAUSE
RET
; Draw bottom paddle
; V0 := --- (m)
; V1 := --- (m)
; VD := paddle coord
DRAWBPADL: CALL SPLITPOS ; get paddle position
ADD V0, #60
CALL BOXTOSCR
LD I, BOTTPADL ; draw it
DRW V0, V1, 4
RET
; Draw side paddle
; V0 := --- (m)
; V1 := --- (m)
; VD := paddle coord
DRAWSPADL: CALL SPLITPOS
LD V0, V1
ADD V0, #0A
CALL BOXTOSCR
LD I, SIDEPADL
DRW V0, V1, 8
RET
; Draw crosshair
; V0 := --- (m)
; V1 := --- (m)
; VD := paddle coord
DRAWCRSHR: LD V0, VD
CALL BOXTOSCR
LD I, CROSSHAIR
DRW V0, V1, 8
RET
; All purpose pause subroutine
; V0 := (in) time to delay (m)
PAUSE: ADD V0, #FF
SE V0, 0
JP PAUSE
RET
DRAWRANDB: LD I, RANDBLK
ADD I, VA
LD V0, [I]
CALL GETBITADDR
LD V0, 108
LD V1, 28
DRW V0, V1, 8
RET
; Progress flow through current box
; V0 := --- (m)
; V1 := --- (m)
; V2 := --- (m)
; V3 := --- (m)
; V9 := current box type
; VA := box progression so far
; VB := flow direction
; VC := current box pos
PROGRESS: CALL DRAWRANDB
ADD VA, 1
LD V0, V9 ; Get box type
LD V1, #F0
AND V0, V1 ; if box is a corner (type = #1X)
SNE V0, 0 ; then see if need to change direction
JP KEEPDIR
SNE VA, 4
JP CORNERPROG
SNE VA, 5
JP ENDPROG
KEEPDIR: LD V2, VA ; store progression in v2
SE VB, 0 ; invert progression if moving up
JP NOINVERT ; ^- you will see why below (y position)
LD V2, 8
SUB V2, VA
NOINVERT: LD V0, VB ; store flow direction in v0
SHR V0
SHR V0
SE V0, 0 ; if flowing right left, skip to R_L_PROG
JP R_L_PROG
SE VB, 0 ; if flowing down, subtract one from progression
ADD V2, #FF ; ^- graphical adjustment
LD V0, VC ; copy box coord to v0
CALL BOXTOSCR ; convert to screen coord, v0=x,v1=y
ADD V1, V2 ; add progression to y coord for screen pos
LD I, VERTMOVE ; load address of vert moving flow
DRW V0, V1, 1 ; draw vert moving flow
SNE VF, 0 ; if collision took place
JP SKIPIT ; check to make sure it
SE VA, 1 ; was only with crosshair
JP SKIPIT ; so end of vertical flow
LD V9, #00 ; else end the game
JP ENDGAME
CORNERPROG: XOR VB, V9 ; CHECK THIS OUT! Those value assignments
LD V0, #07 ; for box and direction aren't arbitrary
AND VB, V0
LD V0, VC
CALL BOXTOSCR ; get box coord
SE V9, B_SE
JP FCASE2 ; find proper bitmap to draw
LD I, SEFLOW ; according to type of corner
ADD V1, 4
FCASE2: SE V9, B_NE
JP FCASE3
LD I, NEFLOW
ADD V1, 2
FCASE3: SE V9, B_SW
JP FCASE4
LD I, SWFLOW
ADD V1, 4
FCASE4: SE V9, B_NW
JP FENDCASE
LD I, NWFLOW
ADD V1, 2
FENDCASE: DRW V0, V1, 2 ; draw bitmap
JP ENDPROG ; end of corner flow
R_L_PROG: SE VB, 5 ; skip to right program if moving right
JP RIGHTPRG
LD V3, #80 ; start with 10000000 bitmap graphic
LEFTPRG: SNE V2, 8 ; iterate over progressions left
JP R_L_DRAW
SHR V3 ; build proper sprite by shifting 1 digit right
ADD V2, 1 ; for each progression not obtained
JP LEFTPRG ; end of left flow
RIGHTPRG: LD V3, #01 ; start with 00000001
RIGHTPRG2: SNE V2, 8 ; iterate over progressions left
JP R_L_DRAW
SHL V3 ; build proper sprite
ADD V2, 1
JP RIGHTPRG2 ; end of right flow
R_L_DRAW: LD V1, V3
LD V0, V3
LD I, TEMP
LD [I], V1 ; store built sprite doubled in memory
LD I, TEMP
LD V0, VC
CALL BOXTOSCR ; get position of box to progress flow
ADD V1, 3
SE V9, B_CROS ; "tunnel under" if a crossbar and on 4,5 progr
JP DRAWIT ; else draw the progression
SNE VA, 4
JP NODRAW
SE VA, 5
DRAWIT: DRW V0, V1, 2 ; write sprite to screen
NODRAW: SNE VF, 0 ; if collision took place
JP SKIPIT ; check to make sure it
SE VA, 1 ; was only with crosshair
JP SKIPIT ; so end of horizontal flow
LD V9, #00 ; else end the game
JP ENDGAME ;
SKIPIT: SE VA, 8 ; if at end of progression through box
JP ENDPROG
CALL WRITESCORE
LD V0, 0
SCOREIT: ADD V7, 1 ; earn 3 points for each box passed
SE V7, 100
JP SCOREIT2
ADD V8, 1
LD V7, 0
SCOREIT2: ADD V0, 1
SE V0, 3
JP SCOREIT
CALL WRITESCORE
LD VA, 0
CALL GETNEXTBOX ; get next box pos and type
ENDPROG: LD V0, VE ; resest timer for next progress check
LD V1, V8
ADD V1, V7
SNE V1, 0
ADD V0, #B0 ; increase timer if only starting
LD DT, V0
CALL DRAWRANDB
RET
; Wait until space key is pressed
; V0 := --- (m)
WAIT: LD V0, #B
WAIT2: SKP V0 ; wait till press space
JP WAIT2
WAIT3: SKNP V0
JP WAIT3 ; wait till space key released
RET
; Determine if game ends, tally score, and reset for next screen
; Changes everything
ENDGAME: LD V0, #3
LD ST, V0 ; BEEP
CALL WAIT
CLS
LD V2, 0
LD V3, 0
CHECKBONUS: LD I, BOXINFO ; iterate through box grid array
ADD I, V2 ; adding together field
LD V1, [I] ; that has a 1 if flowed through
ADD V2, 2
ADD V3, V1
SE V2, 120
JP CHECKBONUS ; if every box flowed through
SNE V3, 60 ; then give a bonus 100 points
ADD V8, 1
LD I, TSCORE ; get old stored total score
LD V1, [I]
ADD V0, V7 ; add new score to total
LD V3, 100
SUB V0, V3
LD V4, VF
SE V4, 0 ; if over 100
ADD V1, 1 ; increment hundreds digit
SE V4, 1 ; else
ADD V0, 100 ; put back to normal
ADD V1, V8
LD I, TSCORE ; save new total
LD [I], V1
LD V5, V0 ; store tens & ones digit
LD V3, 40 ; x coord to display total
LD V4, 40 ; y coord to display total
LD I, SCORE ; STORE BCD
LD B, V1 ; of hundreds score to memory
LD V2, [I] ; read BCD
DB #F0, #30 ; point to sprite of ten thousands digit
DRW V3, V4, 10
ADD V3, 11
DB #F1, #30 ; point to sprite of thousands digit
DRW V3, V4, 10
ADD V3, 11
DB #F2, #30 ; point to sprite of hundreds digit
DRW V3, V4, 10
LD I, SCORE ; STORE BCD
LD B, V5 ; of tens & ones score to memory
LD V2, [I] ; read BCD
ADD V3, 11
DB #F1, #30 ; point to sprite of tens digit
DRW V3, V4, 10
ADD V3, 11
DB #F2, #30 ; point to sprite of ones digit
DRW V3, V4, 10
CALL WRITESCORE ; write score of last job in corner
LD I, LEVEL
LD V0, [I]
LD VE, V0 ; get stored level in case FAST used
SNE VE, #02 ; don't go beyond level 10
ADD VE, #04
ADD VE, #FC ; make level harder
SE V8, 0
JP GOODSCORE ; check if score good enough to continue
SHR V0 ; need 100 - (41 - 2 * LEVEL) pts
LD V1, 100 ; in order to continue
SUB V1, V0 ; LVL 1 -> 61
SUB V7, V1 ; LVL 2 -> 63
SNE VF, 0 ; LVL 3 -> 65, and so on
JP GAMEOVER ; if not, gameover
GOODSCORE: CALL DROPWAIT ; show the dripping graphic and wait
SE V0, #0 ; if pause game key (.) not pressed
JP START ; go to next job
LD V3, #1 ; signal flag that game is to continue
JP PAUSEGAME
GAMEOVER: LD I, HDOVER ; print 'OVER' on screen
LD V0, 42
LD V1, 24
DRW V0, V1, 5
ADD V0, 8
LD V2, 5
ADD I, V2
DRW V0, V1, 5
CALL DROPWAIT ; show the dripping graphic and wait
LD V3, #0 ; signal that game not to be resumed
PAUSEGAME: LD I, TSCORE ; get old stored total score
LD V1, [I]
LD V2, VE
DB #F3, #75 ; store total score in user flags
LD V0, #B
NOSPCPRESS: SKNP V0
JP NOSPCPRESS
LD V0, #0
NOPERPRESS: SKNP V0
JP NOPERPRESS
DB #00, #FD ; exit game
; Wait with drop graphic
; V0 := --- (m)
; V1 := --- (m)
; V2 := --- (m)
; V3 := --- (m)
; V4 := --- (m)
DROPWAIT: LD I, HORZBOX ; draw faucet type pipe
LD V3, 2
LD V4, 8
DRW V3, V4, 8
LD I, SWBOX
LD V3, 10
DRW V3, V4, 8
LD I, DROP ; draw drop and animate
DROPIT: LD V3, 14
LD V4, 16
DRW V3, V4, 7
DRAWDROP: LD V0, #25
CALL PAUSE
LD V0, #B
SKNP V0
JP ENDDROP
LD V0, #0
SKNP V0
JP ENDDROP
DRW V3, V4, 7
ADD V4, 2
SNE V4, 56
JP DROPIT
DRW V3, V4, 7
JP DRAWDROP
ENDDROP: RET
; Get screen coord from box coord
; V0 := (in) box coord, (out) screen x
; V1 := (out) screen y
BOXTOSCR: LD V1, V0
LD VF, #F0
AND V1, VF
SHR V1 ; get y part of box coord
LD VF, #0F
AND V0, VF ; get x part of box coord
SHL V0 ; multipy box coords by 8
SHL V0
SHL V0
ADD V0, 16 ; add proper offsets to get screen coord
ADD V1, 2
RET
; Get box coord from screen coord
; V0 := (in) screen x, (out) box coord
; V1 := (in) screen y, (m)
SCRTOBOX: ADD V0, #F0 ; substr proper offsets
ADD V1, #FE
SHR V0 ; divide screen coords by 8
SHR V0
SHR V0
SHL V1
ADD V0, V1 ; put together into one register
RET
; Get grid array addr from box coord
; V0 := (in) box coord (m)
; V1 := (m)
; I := addr
BOXTOADDR: LD I, BOXINFO ; set address to beginning of box array
LD V1, V0
LD VF, #0F
AND V1, VF
SHL V1
ADD I, V1 ; add x offset (2 * box x)
LD VF, #F0
AND V0, VF
SHR V0
LD V1, V0
SHR V1
SHR V1
ADD V0, V1
SHL V0
ADD I, V0 ; add y offset (20 * box y)
RET
; Draws a box on the grid if possible. if not, penalize
; V0 := box coord (m)
; V1 := --- (m)
; V2 := box type (m)
; V3 := --- (m)
; V4 := --- (m)
; V5 := --- (m)
DRAWBOX: LD V3, V0 ; push box coord
CALL BOXTOADDR ; set I to array address
LD V1, [I] ; read in current box
LD V5, 0
SE V0, #0B ; if box already placed there,
LD V5, #FF ; then penalty
SNE V1, 00 ; if box full
JP DRAWBOX2
LD V1, #3 ; then disallow
LD ST, V1 ; and beep
JP SKIPDRAW
DRAWBOX2: CALL GETBITADDR ; get mask addr for current box
LD V0, V3 ; pop box coord
CALL BOXTOSCR ; convert to scr coord
DRW V0, V1, 8 ; erase current box
LD V0, V3 ; pop box coord
CALL BOXTOADDR ; set I to array address
LD V1, 0
LD V0, V2
LD [I], V1 ; write box type to array
LD V0, V2
CALL GETBITADDR ; get mask addr for box
LD V0, V3 ; pop box coord
CALL BOXTOSCR ; get screen coord
DRW V0, V1, 8 ; draw desired box
SKIPDRAW: CALL WRITESCORE
ADD V7, V5 ; substract penalty
SE V7, #FF ; if V7 was not 0
JP NOADJUST ; no adjustment needed
SNE V8, 0 ; else if V8 is 0
JP ZEROOUT ; set job score to 0
ADD V8, #FF ; else substract 100
LD V7, 99 ; and add 99
JP NOADJUST
ZEROOUT LD V7, 0
NOADJUST: CALL WRITESCORE
RET
; Gets bitmap address for box type
; V0 := box type
; V1 := --- (m)
GETBITADDR: LD V1, #0F
AND V0, V1 ; get offset to mask for box
SHL V0
SHL V0
SHL V0
LD I, ZEROBOX ; set I to mask address
ADD I, V0 ; add offset
RET
; Get box type from storage array and mark it as unchangable
; V0 := (m)
; V1 := (m)
; V3 := (in) box pos
; VC := (in) box pos
; V9 := (out) box type
GETBOXTYPE: LD V0, VC ; get array addr from box pos
CALL BOXTOADDR
LD V1, [I] ; read boxtype
SNE V0, #0B
JP ENDGAME
LD V9, V0
LD V0, VC
CALL BOXTOADDR ; prevent change of box
LD V0, V9
LD V1, #01
LD [I], V1
RET
; Get box coord for next box depending on direction from last
; V0 := --- (m)
; V1 := --- (m)
; V2 := --- (m)
; VB := direction of flow
; VC := (in) curr box coord, (out) next box coord
GETNEXTBOX: LD V3, #00
SNE VB, F_RIGHT
LD V3, #01 ; if right, add one to x
SNE VB, F_DOWN
LD V3, #10 ; if down, add one to y
SNE VB, F_UP
LD V3, #F0 ; if up, substract 1 from y
SNE VB, F_LEFT
LD V3, #FF ; if left, subtract 1 from x
LD V1, VC
ADD V1, V3 ; adjust
LD VF, #F0
AND V1, VF
SNE V1, #F0 ; if gone off top
JP ENDGAME
SNE V1, #60 ; if gone off bottom
JP ENDGAME
LD V1, VC
ADD V1, V3
LD VF, #0F
AND V1, VF
SNE V1, #0F ; if gone off left
JP ENDGAME
SNE V1, #0A ; if gone off right
JP ENDGAME
ADD VC, V3
CALL GETBOXTYPE
RET
; Get a new preview box and update list
; V0 := --- (m)
; V1 := --- (m)
; V2 := --- (m) , (out) box type dropped
; V3 := --- (m)
; V4 := --- (m)
; V5 := --- (m)
NEWPREV: LD V1, VA
JP GOTIT
GETRANDBLK: RND V1, 7 ; randomly determine new box
SHR V0
SHR V0
SNE V0, 0 ; if favoring corners (V0 = 0,1,2,3)
SHR V1 ; divide offset by 2
GOTIT: LD I, RANDBLK
ADD I, V1
LD V0, [I]
LD V5, V0 ; store new box type in V5
LD V4, 3 ; top preview box coord
LD V3, 0
NEXTPREV: LD I, PBOXINFO ; shift old box graphics down
ADD I, V3
LD V0, [I]
LD V2, V0
CALL GETBITADDR ; erase old box graphic
LD V0, 4
DRW V0, V4, 8
LD I, PBOXINFO
ADD I, V3
LD V0, V5
LD [I], V0
CALL GETBITADDR ; draw new box graphic
LD V0, 4
DRW V0, V4, 8
ADD V4, 12
LD V5, V2
ADD V3, 1
SE V3, 5
JP NEXTPREV
RET
; Write the score to screen
; V0 := --- (m)
; V1 := --- (m)
; V2 := --- (m)
; V3 := --- (m)
; V4 := --- (m)
; V7 := (in) score
WRITESCORE: LD V3, 105 ; x pos
LD V4, 9 ; y pos
LD I, SCORE ; write BCD
LD B, V8 ; of hundred score to memory
LD V2, [I] ; read BCD
LD F, V2 ; point to sprite of hundreds digit
DRW V3, V4, 5
ADD V3, 6
LD I, SCORE ; write BCD
LD B, V7 ; of tens and ones score to memory
LD V2, [I] ; read BCD
LD F, V1 ; point to sprite of tens digit
DRW V3, V4, 5
ADD V3, 6
LD F, V2 ; point to sprite of ones digit
DRW V3, V4, 5
RET
; Write the level to screen
; V0 := --- (m)
; V1 := --- (m)
; V2 := --- (m)
; V3 := --- (m)
; V4 := --- (m)
; VE := (in) level
WRITELEVEL: LD V0, VE ; convert speed to game level
ADD V0, #FE
SHR V0
SHR V0
LD V1, 20
SUB V1, V0
LD I, SCORE ; write BCD
LD B, V1 ; of level to memory
LD V2, [I] ; read BCD
DB #F1, #30 ; point to sprite of tens digit
LD V3, 104
LD V4, 50
DRW V3, V4, 10
ADD V3, 11
DB #F2, #30 ; point to sprite of ones digit
DRW V3, V4, 10
RET
; ******************
; START OF DATA AREA
; ******************
RBORDER: DW #F8F8
PRV1BOX: DW #C0C0, #C0C0, #C0C0, #C0C0, #C0C0, #C0FF
PRV2BOX: DW #0303, #0303, #0303, #0303, #0303, #03FF
LEVEL: DW #0000
ZEROBOX: DW #0000, #0000, #0000, #0000 ;0 blank box
VERTBOX: DW #C3C3, #C3C3, #C3C3, #C3C3 ;1 vertical pipe
HORZBOX: DW #FFFF, #0000, #0000, #FFFF ;2 horizontal pipe
CROSBOX: DW #C3C3, #0000, #0000, #C3C3 ;3 crossing pipes
FULLBOX: DW #FFFF, #FFFF, #FFFF, #FFFF ;4 full box
SWBOX: DW #FFFF, #0F07, #0303, #83C3 ;5 south to west pipe
SEBOX: DW #FFFF, #F0E0, #C0C0, #C1C3 ;6 south to east pipe
ESTRBOX: DW #FFFF, #C0C0, #C0C0, #FFFF ;7 east open start pipe
WSTRBOX: DW #FFFF, #0303, #0303, #FFFF ;8 west open start pipe
NSTRBOX: DW #C3C3, #C3C3, #C3C3, #FFFF ;9 north open start pipe
SSTRBOX: DW #FFFF, #C3C3, #C3C3, #C3C3 ;A south open start pipe
GRID: DW #007E, #4242, #4242, #7E00 ;11 (B) empty grid site
TEMP: DW #0000, #0000, #0000, #0000 ;12 (C) temp memory area
NEBOX: DW #C3C1, #C0C0, #E0F0, #FFFF ;13 (D) north to east pipe
NWBOX: DW #C383, #0303, #070F, #FFFF ;14 (E) north to west pipe
CROSSHAIR: DW #0000, #183C, #3C18, #0000 ;15 (F)
SIDEPADL: DW #0010, #1070, #7010, #1000
BOTTPADL: DW #0018, #187E
VERTMOVE: DW #1800 ; bitmap of vertical flow
SEFLOW: DW #0804
NEFLOW: DW #0408
SWFLOW: DW #1020
NWFLOW DW #2010
RANDBLK: DW #1D15, #161E, #0102, #0303 ; used for random block select
RANDDIR: DW #0607, #0508, #0009, #030A ; used for random direction
PBOXINFO: DW #0000, #0000, #0000 ; preview box info
SCORE: DW #0000, #0000 ; total score storage
TSCORE: DW #0000, #0000 ; temp score area
TITLE: DW #A3A2, #E3A2, #AABB, #9293, #123A
TITLE2: DW #BBA2, #B322, #3A88, #8888, #4048
HDSCORE: DW #D992, #D252, #D93B, #AAB3, #AA2B
HDLEVEL: DW #9A92, #9A91, #D9B4, #A4B4, #2436
HDOVER: DW #EAAA, #AEA4, #E4EE, #8ACE, #89E9
DROP: DW #2020, #70F8, #F8F8, #7000
BOXINFO: DW #0B00, #0B00, #0B00, #0B00, #0B00 ; 60x2 array for
X1: DW #0B00, #0B00, #0B00, #0B00, #0B00 ; storage of grid
X2: DW #0B00, #0B00, #0B00, #0B00, #0B00 ; placements and
X3: DW #0B00, #0B00, #0B00, #0B00, #0B00 ; flow control
X4: DW #0B00, #0B00, #0B00, #0B00, #0B00
X5: DW #0B00, #0B00, #0B00, #0B00, #0B00
X6: DW #0B00, #0B00, #0B00, #0B00, #0B00
X7: DW #0B00, #0B00, #0B00, #0B00, #0B00
X8: DW #0B00, #0B00, #0B00, #0B00, #0B00
X9: DW #0B00, #0B00, #0B00, #0B00, #0B00
X10: DW #0B00, #0B00, #0B00, #0B00, #0B00
X11: DW #0B00, #0B00, #0B00, #0B00, #0B00
--
Paul Raines
Georgia Institute of Technology, Atlanta Georgia, 30332
uucp: ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!vapsppr
Internet: vapsppr@prism.gatech.edu